package Test;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import weaver.common.DateUtil;

import javax.xml.bind.annotation.adapters.HexBinaryAdapter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Set;


public class Demo {


    public static void main(String[] args) {
        String target = "/";
        String baseDirPath = "/Users/dusongsong/Downloads";
        String appid = "oa";
        String md5 = generateMD5("123456");
        String tarDirName = appid + "-" + getDateDir("") + "-" + md5;
        String fullTarDirPath = baseDirPath + target + tarDirName;
        String fullTarDirName = fullTarDirPath + ".tar";
        String timestamp = generateMD5("544321");
        String destFileName = "test.doc";
        try {
             // 2. 创建File对象
                File file = new File(baseDirPath+"/nfs文件服务器配置.doc");

                // 3. 使用FileInputStream构造器创建InputStream
                FileInputStream fileInputStream = new FileInputStream(file);
                createFile(fileInputStream, fullTarDirPath + target + timestamp, destFileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        boolean archiveDirStatus = archiveDirectoryToXml(fullTarDirPath + target + "档案包目录.xml");
        boolean createTarStatus = createTarFromDirectory(fullTarDirPath, fullTarDirName);
    }


    //档案目录封装
    public static boolean archiveDirectoryToXml(String filepath) {
        boolean flag = false;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.newDocument();
            Element root = document.createElement("档案目录");
            document.appendChild(root);
            Element wj_element = document.createElement("文件");
            root.appendChild(wj_element);
            wj_element.appendChild(document.createElement("文件顺序号")).appendChild(document.createTextNode(" "));
            wj_element.appendChild(document.createElement("元数据路径")).appendChild(document.createTextNode("2"));
            flag = documentToPrettyXmlFile(document, filepath);
//            File file = new File("/Users/dusongsong/Downloads/20240526/1.text");
//            file.createNewFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    //转漂亮的xml字符串
    public static boolean documentToPrettyXmlFile(Document document, String filePath) {
        boolean flag = false;
        try {
            if (document != null) {
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
                Transformer transformer = transformerFactory.newTransformer();
                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
                transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
                DOMSource source = new DOMSource(document);
                System.out.println(">>>>>documentToPrettyXmlFile>>>>>filePath: " + filePath);
                File file = new File(filePath);
                String encodedFilename = URLDecoder.decode(file.getName(), "UTF-8");
                System.out.println(">>>>>documentToPrettyXmlFile>>>>>encodedFilename: " + encodedFilename);
                StreamResult result = new StreamResult(file.getParent()+File.separator+encodedFilename);
                transformer.transform(source, result);
                flag = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    //创建tar压缩包
    public static boolean createTarFromDirectory(String sourceDirPath, String tarFilePath) {
        System.out.println(">>>>>createTarFromDirectory>>>>>tarFilePath: " + tarFilePath);
        System.out.println(">>>>>createTarFromDirectory>>>>>sourceDirPath: " + sourceDirPath);
        boolean status = true;
        try {
            FileOutputStream fos = new FileOutputStream(tarFilePath);
            TarArchiveOutputStream tarOut = new TarArchiveOutputStream(fos, "UTF-8");
            // 获取源目录
            Path sourceDirectory = Paths.get(sourceDirPath);
            // 添加文件或文件夹到tar
            addFilesToTar(tarOut,sourceDirectory, sourceDirectory.getParent().toString().length());
            if(sourceDirectory.toFile().exists()){
                status = deleteDirectory(sourceDirPath);
            }
        } catch (IOException e) {
        }
        return status;
    }

    private static boolean deleteDirectory(String directoryPath) {
        // 创建File对象
        File directory = new File(directoryPath);
        // 检查是否存在且是一个目录
        if (directory.exists() && directory.isDirectory()) {
            deleteDirectoryRecursively(directory);

            return true;
        } else {

            return false;
        }
    }

    private static boolean deleteDirectoryRecursively(File dir) {
        // 如果目录不为空
        if (dir.isDirectory()) {
            // 遍历目录中的每个文件和子目录
            String[] children = dir.list();
            if (children != null) {
                for (String child : children) {
                    // 递归删除子目录或文件
                    boolean success = deleteDirectoryRecursively(new File(dir, child));
                    if (!success) {
                        return false;
                    }
                }
            }
        }

        // 尝试删除目录本身
        return dir.delete();
    }

    //新增文件到压缩包
    private static void addFilesToTar(TarArchiveOutputStream tarOut, Path sourceDir, int basePathLength) {
        try {
            Files.walk(sourceDir)
                    .filter(Files::isRegularFile)
                    .forEach(file -> {
                        try {
                            System.out.println(">>>>>addFilesToTar>>>>>file="+file);
                            System.out.println(">>>>>addFilesToTar>>>>>basePathLength="+basePathLength);
                            String entryPath = file.toString().substring(basePathLength + 1);
                            System.out.println(">>>>>addFilesToTar>>>>>entryPath="+entryPath);
                            TarArchiveEntry entry = new TarArchiveEntry(file.toFile(), entryPath);
                            tarOut.putArchiveEntry(entry);
                            entry.setSize(file.toFile().length());
                            BufferedInputStream in = new BufferedInputStream(new FileInputStream(file.toFile()));
                            IOUtils.copy(in, tarOut);
                            tarOut.closeArchiveEntry();
                            in.close();

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    });
            tarOut.finish();
        } catch (IOException e) {
            System.out.println(">>>>>addFileToTarGz>>>>>Error adding file to tar: " + sourceDir.toString() + " - " + e.getMessage());
        }
    }
    public static boolean createFile(InputStream inputStream, String destFilePath, String destFileName) {
        boolean flag = false;
        System.out.println(">>>>>createFile>>>>>destFilePath=" + destFilePath);
        System.out.println(">>>>>createFile>>>>>destFileName=" + destFileName);
        try {
            boolean isMkDir = createDirectory(destFilePath);
            System.out.println(">>>>>createFile>>>>>isMkDir=" + isMkDir);
            if (isMkDir) {
                FileOutputStream outputStream = new FileOutputStream(destFilePath + "/" + destFileName);
                byte[] buffer = new byte[1024]; // 缓冲区
                int length; // 读取的长度
                // 从输入流读取数据并写入输出流
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
                outputStream.close();
                flag = true;
                System.out.println(">>>>>createFile>>>>>文件创建成功");
            }
        } catch (IOException e) {
            System.out.println(">>>>>createFile>>>>>文件创建失败：" + e.getMessage());
        }
        return flag;
    }

    //创建目录
    private static boolean createDirectory(String destDirName) {
        System.out.println(">>>>>createDirectory>>>>>destDirName=" + destDirName);
        // 创建File对象
        File dir = new File(destDirName);
        boolean flag = false;
        // 判断目录是否存在
        if (!dir.exists()) {// 如果目录不存在，则创建目录，包括任何必须的父目录
            try {
                flag = dir.mkdirs(); // 创建多级目录
            } catch (SecurityException se) {
                System.out.println(">>>>>createDirectory>>>>>处理没有权限创建目录的异常: " + se.getMessage());
            }
        } else {
            flag = true;
            System.out.println(">>>>>createDirectory>>>>>Directory already exists: " + dir.getAbsolutePath());
        }
        return flag;
    }
    //按日期生成目录
    public static String getDateDir(String target) {
        String currentDate = DateUtil.getCurrentDate();
        String year = currentDate.substring(0, 4);
        String month = currentDate.substring(5, 7);
        String day = currentDate.substring(8, 10);
        return year + target + month + target + day;
    }

    // 使用Apache Commons Codec直接生成MD5哈希
    public static String generateMD5(String input) {
        return DigestUtils.md5Hex(input);
    }

    //获取时间戳
    public static String getTimestamp() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return sdf.format(new Date());
    }

    private static void passwordHashSalt() {
        try {
            String password = "123456";
            String salt = "1abd1c";
            // 创建SHA-256摘要对象
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update((password + salt).getBytes());
            // 计算哈希值
            byte[] result = messageDigest.digest();
            // 将哈希值转换为十六进制字符串
            String hexString = new HexBinaryAdapter().marshal(result);
            System.out.println("Original String: " + password);
            System.out.println("SHA-256 Hash: " + hexString.toLowerCase());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String InsertSql(Map<String, String> zd) {
        String TABLENAME = "formtable_main_152";
        StringBuffer sql = new StringBuffer("insert into " + TABLENAME + "_dt1(");
        Set<String> set = zd.keySet();
        for (String string : set) {
            sql.append(string + ",");
        }
        sql = sql.deleteCharAt(sql.length() - 1);
        sql.append(") values(");
        for (String string : set) {
            sql.append("'" + zd.get(string) + "',");
        }
        sql = sql.deleteCharAt(sql.length() - 1);
        sql.append(")");
        return sql.toString();

    }

    public static void readExcel(String filePath) {
        try (FileInputStream fis = new FileInputStream(filePath)) {
            Workbook workbook;
            if (filePath.endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(fis);
            } else if (filePath.endsWith(".xls")) {
                workbook = new HSSFWorkbook(fis);
            } else {
                throw new IllegalArgumentException("Unsupported file format!");
            }

            Sheet sheet = workbook.getSheetAt(0);
            // ... 继续进行读取操作 ...
            for (Row row : sheet) {
                for (Cell cell : row) {
                    String cellValue = "";
                    switch (cell.getCellType()) {
                        case STRING:
                            cellValue = cell.getStringCellValue();
                            break;
                        case NUMERIC:
                            cellValue = Double.toString(cell.getNumericCellValue());
                            break;
                        // 处理其他类型如 BOOLEAN, FORMULA, ERROR 等
                    }
                    System.out.print(cellValue + "\t");
                }
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


// 注意替换 "path_to_your_file.xlsx" 为你要读取的实际文件路径